﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Abp.Runtime.Security;
using Abp.Runtime.Session;
using Hicap.AuthorizationServer.Core.Common;
using Hicap.AuthorizationServer.Core.Managers;
using Microsoft.AspNetCore.SignalR;

namespace Hicap.AuthorizationServer.Core.Notify
{
    public class NotifyHub : Hub
    {
        private readonly INotificationManager _notificationManager;
        private string _type = NotificationType.UserActive;
        private readonly IAbpSession _session;

        public NotifyHub(INotificationManager notificationManager)
        {
            _notificationManager = notificationManager;
            _session = NullAbpSession.Instance;
        }

        public string @Type
        {
            get => _type;
            set
            {
                if (!string.IsNullOrEmpty(value)) _type = value;
            }
        }

        private string UserId
        {
            get
            {
                if (Context?.User == null) return "anonymous";
                var claims = Context.User.Claims;
                var userIdClaim = claims.FirstOrDefault(x => x.Type.Equals(AbpClaimTypes.UserId));
                return userIdClaim != null ? userIdClaim.Value : "anonymous";
            }
        }

        public override async Task OnConnectedAsync()
        {
            if (string.IsNullOrEmpty(UserId)) return;
            await Groups.AddToGroupAsync(Context.ConnectionId, UserId);
            await Clients.Client(Context.ConnectionId).SendAsync(NotificationMethod.Connected, $"{Context.ConnectionId} is Connected.");
            if (HaveActiveAuth())
            {
                await Groups.AddToGroupAsync(Context.ConnectionId, @Type);
                var message = await _notificationManager.ReadMessage(@Type);
                message.ForEach(async x => await SendToGroup(x));
                await base.OnConnectedAsync();
            }
        }

        private bool HaveActiveAuth()
        {
            //            var claims = Context.User.Claims;
            var authCodes = _session.GetAuthCodes().Split(",");
            var haveActiveAuth = authCodes != null && authCodes.Any(x => x.Equals(@Type));

            return haveActiveAuth;
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {
            if (string.IsNullOrEmpty(UserId)) return;
            await Groups.RemoveFromGroupAsync(Context.ConnectionId, UserId);
            await base.OnDisconnectedAsync(exception);
        }

        public async Task SendToGroup(string message)
        {
            if (string.IsNullOrEmpty(message)) return;
            if (string.IsNullOrEmpty(UserId)) return;
            await Clients.Group(UserId).SendAsync(NotificationMethod.GenerationTaskFeedBack, message);
        }
    }
}